home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Mania 5
/
MacMania 5.toast
/
/
Internet software
/
NewsWatcher
/
NW Source
/
Source
/
text.c
< prev
next >
Wrap
Text File
|
1997-01-09
|
29KB
|
1,216 lines
/*----------------------------------------------------------------------------
text.c
This module handles read-only text windows.
Copyright © 1994-1997, Northwestern University.
----------------------------------------------------------------------------*/
#include <string.h>
#include <ctype.h>
#include "glob.h"
#include "text.h"
#include "menus.h"
#include "tescroll.h"
#include "url.h"
#include "newswatcher.h"
#include "drawutil.h"
#include "windutil.h"
#include "memutil.h"
#include "dialog.h"
#include "teutil.h"
#include "wind.h"
#include "about.h"
#include "dragutil.h"
#include "print.h"
#include "status.h"
#include "fileutil.h"
#include "strutil.h"
#include "sfutil.h"
#include "group.h"
#include "key.h"
#include "ic.h"
#include "help.h"
#define kMinWindowWidth 410 /* minimum window width */
static TEClickLoopUPP gAutoScrollUPP;
static ControlActionUPP gScrollActionUPP;
/*----------------------------------------------------------------------------
GetTextRect
Compute the "text" rectangle of a text window
Entry: wind = pointer to text window.
Exit: *textRect = text rectangle.
The "text" rectangle is the area of the window where the text is
displayed: the window portrect, minus the panel area, minus the scroll
bars, minus the text margin.
----------------------------------------------------------------------------*/
static void GetTextRect (WindowPtr wind, Rect *textRect)
{
TWindow **info;
info = (TWindow**)GetWRefCon(wind);
*textRect = wind->portRect;
textRect->top += (**info).panelHeight;
textRect->bottom -= 15;
textRect->right -= 15;
InsetRect(textRect, kTextMargin, kTextMargin);
}
/*----------------------------------------------------------------------------
FixHeight
Round down window height to an exact multiple of lines.
Entry: wind = pointer to text window.
*height = window height.
Exit: *height = adjusted window height
----------------------------------------------------------------------------*/
static void FixHeight (WindowPtr wind, short *height)
{
TWindow **info;
short panelHeight, lineHeight, adjust;
info = (TWindow**)GetWRefCon(wind);
panelHeight = (**info).panelHeight;
lineHeight = (**info).lineHeight;
adjust = panelHeight + 15 + 2*kTextMargin;
*height = (*height - adjust) / lineHeight * lineHeight + adjust;
}
/*----------------------------------------------------------------------------
MinHeight
Compute the minimum height of a text window.
Entry: wind = pointer to text window.
----------------------------------------------------------------------------*/
static short MinHeight (WindowPtr wind)
{
TWindow **info;
short lineHeight, height, extra;
info = (TWindow**)GetWRefCon(wind);
lineHeight = (**info).lineHeight;
extra = lineHeight + 15 + 2*kTextMargin;
if (extra < 65) extra = 65 + lineHeight;
height = (**info).panelHeight + extra;
FixHeight(wind, &height);
return height;
}
/*----------------------------------------------------------------------------
ScrollAction
Vertical scroll bar action proc.
Entry: vScroll = handle to vertical scroll bar control.
part = part code.
----------------------------------------------------------------------------*/
static pascal void ScrollAction (ControlHandle vScroll, short part)
{
WindowPtr wind;
TWindow **info;
TEHandle theTE;
wind = (**vScroll).contrlOwner;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
TEScrollScrollByPartCode(theTE, vScroll, part);
}
/*----------------------------------------------------------------------------
AutoScroll
Handle text window autoscrolling.
Exit: function result = true
----------------------------------------------------------------------------*/
static pascal Boolean AutoScroll (void)
{
WindowPtr wind;
TWindow **info;
ControlHandle vScroll;
TEHandle theTE;
wind = MyFrontWindow();
if (wind == nil) return true;
info = (TWindow**)GetWRefCon(wind);
vScroll = (**info).vScroll;
theTE = (**info).theTE;
TEScrollAutoScroll(theTE, vScroll);
return true;
}
/*----------------------------------------------------------------------------
ResizeContents
Adjust a text window's contents after a window size change (grow
or zoom).
Entry: wind = pointer to text window.
----------------------------------------------------------------------------*/
static void ResizeContents (WindowPtr wind)
{
TWindow **info;
short width, height, panelHeight;
ControlHandle vScroll;
TEHandle theTE;
Rect r;
info = (TWindow**)GetWRefCon(wind);
panelHeight = (**info).panelHeight;
vScroll = (**info).vScroll;
theTE = (**info).theTE;
width = wind->portRect.right;
height = wind->portRect.bottom;
SetRect(&r, width-15, panelHeight-1, width+1, height-14);
(**vScroll).contrlRect = r;
GetTextRect(wind, &r);
(**theTE).viewRect = (**theTE).destRect = r;
TECalText(theTE);
SetControlValue(vScroll, 0);
TEScrollAdjustScrollMax(theTE, vScroll);
TEScrollScrollSelectionIntoView(theTE, vScroll);
InvalRect(&wind->portRect);
}
/*----------------------------------------------------------------------------
MakeNewTextWindow
Create a new text window.
Entry: title = window title, P-format.
panelHeight = panel height.
drawPanel = pointer to panel drawing function, or nil if none.
text = handle to text.
Exit: function result = error code.
*theWindow = pointer to new window.
----------------------------------------------------------------------------*/
OSErr MakeNewTextWindow (StringPtr title, short panelHeight,
void (*drawPanel)(WindowPtr), Handle text, WindowPtr *theWindow)
{
short width, height;
WindowPtr wind = nil;
TWindow **info;
Rect r;
TEHandle theTE;
ControlHandle vScroll;
OSErr err = noErr;
char state;
GrafPtr port;
long len;
MyICReadSharedPrefs(kICScreenFont);
GetPort(&port);
err = CreateNewWindow(kText, title, gPrefs.textFont, gPrefs.textSize, &wind);
if (err != noErr) return err;
SetPort(wind);
info = (TWindow**)GetWRefCon(wind);
(**info).panelHeight = panelHeight;
(**info).drawPanel = drawPanel;
width = kMinWindowWidth;
height = MinHeight(wind);
PositionNewWindow(wind, width, height);
GetTextRect(wind, &r);
theTE = TENew(&r, &r);
(**theTE).clickLoop = gAutoScrollUPP;
if (gHaveTEOutlineHilite) TEFeatureFlag(teFOutlineHilite, TEBitSet, theTE);
(**info).theTE = theTE;
SetRect(&r, width-15, panelHeight-1, width+1, height-14);
vScroll = NewControl(wind, &r, "\p", true, 0, 0, 0, scrollBarProc, 1);
(**info).vScroll = vScroll;
state = MyHGetState(text);
MyHLock(text);
len = MyGetHandleSize(text);
if (len > kMaxShort) len = kMaxShort;
err = MyTESetText(*text, len, theTE);
MyHSetState(text, state);
if (err != noErr) goto exit;
TESetSelect(0, 0, theTE);
err = DoZoom(wind, inZoomOut);
if (err != noErr) goto exit;
TEScrollAdjustScrollMax(theTE, vScroll);
MyShowWindow(wind);
*theWindow = wind;
SetPort(port);
return noErr;
exit:
DoClose(wind);
SetPort(port);
return err;
}
/*----------------------------------------------------------------------------
CheckTextWindowAlreadyOpen
Check to see if a text window is already open, and if it is, bring it to
the front.
Entry: title = window title, P-format.
Exit: function result = true if already open window brought to front.
----------------------------------------------------------------------------*/
Boolean CheckTextWindowAlreadyOpen (StringPtr title)
{
WindowPtr wind;
Str255 windTitle;
TWindowKind kind;
wind = FrontWindow();
while (wind != nil) {
kind = GetMyWindowKind(wind);
if (kind == kText) {
GetWTitle(wind, windTitle);
if (EqualString(windTitle, title, false, false)) {
MySelectWindow(wind);
return true;
}
}
wind = (WindowPtr)(((WindowPeek)wind)->nextWindow);
}
return false;
}
/*----------------------------------------------------------------------------
Find
Search a text window for a pattern.
Entry: wind = pointer to text window.
offset = offset into text to begin search.
gFindPattern = pattern.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Find (WindowPtr wind, short offset)
{
TWindow **info;
TEHandle theTE;
Handle hText;
short len;
char state;
long matchOffset;
OSErr err = noErr;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
hText = (**theTE).hText;
len = (**theTE).teLength - offset;
state = MyHGetState(hText);
MyHLock(hText);
err = MyNSubstringSearch(*hText+offset, gFindPattern, len, &matchOffset,
GiveTime);
MyHSetState(hText, state);
if (err != noErr) return err;
if (matchOffset == -1) {
SysBeep(0);
} else {
offset += matchOffset;
TESetSelect(offset, offset + strlen(gFindPattern), theTE);
TEScrollScrollToMiddle(theTE, offset, (**info).vScroll);
}
return noErr;
}
/*----------------------------------------------------------------------------
DoSave
Handle the "Save" command.
Entry: wind = pointer to text window.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr DoSave (WindowPtr wind, short modifiers)
{
Str255 title;
Str31 fileName;
StandardFileReply reply;
Str255 prompt;
OSErr err = noErr;
TWindow **info;
Handle text;
long start, end;
TEHandle theTE;
char state;
short refNum = 0;
Boolean empty;
Boolean needCR;
long length;
char *p;
MyICReadSharedPrefs(kICeditorHelper);
GetWTitle(wind, title);
MakeLegalFileName(title, fileName);
GetPString(kStrSaveFileAsPrompt, prompt);
MyStandardPutFile(prompt, fileName, &reply,
gPrefs.savedArtDefaultFolder ? gPrefs.savedArtDefaultFolderAlias : nil);
if (!reply.sfGood) return userCanceledErr;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
text = (**theTE).hText;
if ((modifiers & shiftKey) == 0) {
start = 0;
end = MyGetHandleSize(text);
} else {
start = (**theTE).selStart;
end = (**theTE).selEnd;
}
state = MyHGetState(text);
err = OpenDataForkWriteCreateIfMissing(&reply.sfFile, gPrefs.savedArtCreator, 'TEXT',
reply.sfScript, false, &refNum, &empty);
if (err != noErr) goto exit;
length = end - start;
MyHLock(text);
for (p = *text + end - 1; p >= *text + start && *p == CR; p--) /* do nothing */;
p++;
if (p < *text + end) {
needCR = false;
length = p + 1 - *text - start;
} else {
needCR = true;
}
err = FSWrite(refNum, &length, *text + start);
if (err != noErr) goto exit;
if (needCR) {
length = 1;
err = FSWrite(refNum, &length, CRSTR);
if (err != noErr) goto exit;
}
MyHSetState(text, state);
MyFSClose(refNum, nil);
return noErr;
exit:
MyHSetState(text, state);
if (refNum != 0) MyFSClose(refNum, nil);
return err;
}
/*----------------------------------------------------------------------------
DoSaveAs
Handle the "Save As" command.
Entry: wind = pointer to text window.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr DoSaveAs (WindowPtr wind, short modifiers)
{
return DoSave(wind, modifiers);
}
/*----------------------------------------------------------------------------
DoPrint
Handle the "Print" command.
Entry: wind = pointer to text window.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr DoPrint (WindowPtr wind, short modifiers)
{
TWindow **info;
TEHandle theTE;
Handle text;
CStr255 title;
OSErr err = noErr;
long start, end;
err = StartPrint();
if (err != noErr) return err;
err = DisplayStatusMessageNumber(kStrPrinting);
if (err != noErr) return err;
GetWTitle(wind, (StringPtr)title);
p2cstr((StringPtr)title);
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
text = (**theTE).hText;
start = (**theTE).selStart;
end = (**theTE).selEnd;
if ((modifiers & shiftKey) == 0 || start >= end) {
start = 0;
end = MyGetHandleSize(text);
}
return PrintText((**theTE).hText, start, end, title);
}
/*----------------------------------------------------------------------------
DoCopy
Handle the "Copy" command.
Entry: wind = pointer to text window.
----------------------------------------------------------------------------*/
static void DoCopy (WindowPtr wind)
{
TWindow **info;
TEHandle theTE;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
MyTECopy(theTE);
}
/*----------------------------------------------------------------------------
DoSelectAll
Handle the "Select All" command.
Entry: wind = pointer to text window.
----------------------------------------------------------------------------*/
static void DoSelectAll (WindowPtr wind)
{
TWindow **info;
TEHandle theTE;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
TESetSelect(0, kMaxShort, theTE);
}
/*----------------------------------------------------------------------------
DoFind
Handle the "Find" command for a text window.
Entry: wind = pointer to text window.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr DoFind (WindowPtr wind)
{
TWindow **info;
TEHandle theTE;
OSErr err = noErr;
err = DoFindDialog();
if (err != noErr) return err;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
return Find(wind, gPrefs.startFindAtBeginning ? 0 : (**theTE).selStart);
}
/*----------------------------------------------------------------------------
DoFindAgain
Handle the "Find Again" command for a text window.
Entry: wind = pointer to text window.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr DoFindAgain (WindowPtr wind)
{
TWindow **info;
TEHandle theTE;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
return Find(wind, (**theTE).selEnd);
}
/*----------------------------------------------------------------------------
DoEnterSelection
Handle the "Enter Selection" command for a text window.
Entry: wind = pointer to text window.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr DoEnterSelection (WindowPtr wind)
{
TWindow **info;
TEHandle theTE;
short selStart, selEnd, len;
Handle hText;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
selStart = (**theTE).selStart;
selEnd = (**theTE).selEnd;
hText = (**theTE).hText;
if (selStart >= selEnd || selEnd > selStart + 255) return noErr;
len = selEnd - selStart;
BlockMoveData(*hText + selStart, gFindPattern, len);
gFindPattern[len] = 0;
return noErr;
}
/*----------------------------------------------------------------------------
Activate
Handle an activate event for a text window.
Entry: wind = pointer to text window.
act = true to activate, false to deactivate
----------------------------------------------------------------------------*/
static void Activate (WindowPtr wind, Boolean act)
{
TWindow **info;
TEHandle theTE;
ControlHandle vScroll;
Rect r;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
vScroll = (**info).vScroll;
if (act) {
ShowControl(vScroll);
TEActivate(theTE);
} else {
HideControl(vScroll);
TEDeactivate(theTE);
}
r = wind->portRect;
r.top = r.bottom - 15;
r.left = r.right - 15;
InvalRect(&r);
}
/*----------------------------------------------------------------------------
Update
Handle an update event for a text window.
Entry: wind = pointer to text window.
----------------------------------------------------------------------------*/
static void Update (WindowPtr wind)
{
TWindow **info;
short panelHeight, windWidth;
Rect r;
TEHandle theTE;
info = (TWindow**)GetWRefCon(wind);
panelHeight = (**info).panelHeight;
theTE = (**info).theTE;
r = wind->portRect;
r.top += panelHeight;
ClipRect(&r);
DrawGrowIcon(wind);
NoClip();
UpdateControls(wind, wind->visRgn);
if (panelHeight > 0) {
(*(**info).drawPanel)(wind);
windWidth = wind->portRect.right - wind->portRect.left;
MoveTo(0, panelHeight-3);
LineTo(windWidth, panelHeight-3);
MoveTo(0, panelHeight-1);
LineTo(windWidth, panelHeight-1);
}
TEUpdate(&wind->portRect, theTE);
}
/*----------------------------------------------------------------------------
Mouse
Handle a mouse down event in the content area of a text window.
Entry: wind = pointer to text window.
where = location of mouse down in local coords.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Mouse (WindowPtr wind, Point where, short modifiers)
{
TWindow **info;
TEHandle theTE;
Rect viewRect;
short part, oldVal, dv;
ControlHandle control, vScroll;
OSErr err = noErr;
Boolean dragged = false, trashed;
short oldSelStart, oldSelEnd;
info = (TWindow**) GetWRefCon(wind);
theTE = (**info).theTE;
vScroll = (**info).vScroll;
viewRect = (**theTE).viewRect;
InsetRect(&viewRect, -kTextMargin, 0);
part = FindControl(where, wind, &control);
if (part != 0 && control == vScroll) {
if (part == inThumb) {
oldVal = GetControlValue(vScroll);
TrackControl(vScroll, where, nil);
dv = GetControlValue(vScroll) - oldVal;
if (dv != 0) TEScrollScrollText(theTE, vScroll, -dv);
} else {
SetControlReference(vScroll, 0);
TrackControl(vScroll, where, gScrollActionUPP);
SetControlReference(vScroll, 1);
TEScrollAdjustScrollMax(theTE, vScroll);
}
} else if (PtInRect(where, &viewRect)) {
if (gHaveDragMgr) {
err = DragText(&gCurEvent, where, theTE, &dragged, &trashed);
if (err != noErr) return err;
}
if (wind == FrontWindow() && !dragged) {
oldSelStart = (**theTE).selStart;
oldSelEnd = (**theTE).selEnd;
MyTEClick(where, (modifiers & shiftKey) != 0, theTE);
err = CommandClick(wind, theTE, oldSelStart, oldSelEnd, modifiers);
if (err != noErr) return err;
}
} else if (where.v < (**info).panelHeight) {
CheckAboutWindowEasterEgg(wind, where, modifiers);
}
return noErr;
}
/*----------------------------------------------------------------------------
Draggable
Determine whether a mouse down event is on a draggable object in a
text window.
Entry: wind = pointer to text window.
where = location of mouse down event, in local coordinates.
modifiers = modifiers field from event record.
Exit: function result = true if object is draggable.
----------------------------------------------------------------------------*/
static Boolean Draggable (WindowPtr wind, Point where, short modifiers)
{
TWindow **info;
TEHandle theTE;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
return PtInTEHiliteRgn(where, theTE);
}
/*----------------------------------------------------------------------------
Key
Handle a key down event for a text window.
Entry: wind = pointer to text window.
theChar = ASCII code of key.
theKey = keyboard code of key.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Key (WindowPtr wind, unsigned char theChar, unsigned char theKey,
short modifiers)
{
TWindow **info;
ControlHandle vScroll;
TEHandle theTE;
OSErr err = noErr;
short scrollIntoView;
TKeypadKey keypadKey;
Boolean isArrow;
info = (TWindow**)GetWRefCon(wind);
vScroll = (**info).vScroll;
theTE = (**info).theTE;
isArrow = IsArrowKey(theChar);
if ((modifiers & cmdKey) != 0 && !isArrow) {
SysBeep(0);
return noErr;
}
if (gPrefs.keypadShortcuts && IsKeypadKey(theChar, theKey, &keypadKey)) {
switch (keypadKey) {
case kKeypadEqualKey:
DoSelectAll(wind);
return noErr;
case kKeypadStarKey:
return DoClose(wind);
case kKeypad1Key:
TEScrollScrollByPartCode(theTE, vScroll, kScrollToEnd);
return noErr;
case kKeypad2Key:
TEScrollScrollByPartCode(theTE, vScroll, inDownButton);
return noErr;
case kKeypad3Key:
TEScrollScrollByPartCode(theTE, vScroll, inPageDown);
return noErr;
case kKeypad7Key:
TEScrollScrollByPartCode(theTE, vScroll, kScrollToHome);
return noErr;
case kKeypad8Key:
TEScrollScrollByPartCode(theTE, vScroll, inUpButton);
return noErr;
case kKeypad9Key:
TEScrollScrollByPartCode(theTE, vScroll, inPageUp);
return noErr;
default:
SysBeep(0);
return noErr;
}
}
if (theChar == pageUpKey) {
TEScrollScrollByPartCode(theTE, vScroll, inPageUp);
return noErr;
}
if (theChar == pageDownKey) {
TEScrollScrollByPartCode(theTE, vScroll, inPageDown);
return noErr;
}
if (theChar == homeKey) {
TEScrollScrollByPartCode(theTE, vScroll, kScrollToHome);
return noErr;
}
if (theChar == endKey) {
TEScrollScrollByPartCode(theTE, vScroll, kScrollToEnd);
return noErr;
}
if (isArrow) {
TEArrowKey(theChar, modifiers, theTE, 0, &gPrevEvent, &scrollIntoView);
TEScrollScrollRangeIntoView(theTE, scrollIntoView, scrollIntoView, vScroll);
return noErr;
}
if (gPrefs.keyboardShortcuts) {
if (theChar == ' ') {
TEScrollScrollByPartCode(theTE, vScroll, inPageDown);
return noErr;
}
theChar = tolower(theChar);
if (theChar == 'w') {
return DoClose(wind);
}
if (theChar == 'a') {
DoSelectAll(wind);
return noErr;
}
}
SysBeep(0);
return noErr;
}
/*----------------------------------------------------------------------------
Grow
Handle a mouse down event in the grow box of a text window.
Entry: wind = pointer to text window.
where = location of mouse down event, in global coordinates.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Grow (WindowPtr wind, Point where)
{
Rect sizeRect;
long size;
short width, height;
SetRect(&sizeRect, kMinWindowWidth, MinHeight(wind), kMaxShort, kMaxShort);
size = GrowWindow(wind, where, &sizeRect);
if (size != 0) {
width = LoWord(size);
height = HiWord(size);
FixHeight(wind, &height);
SizeWindow(wind, width, height, false);
ResizeContents(wind);
}
return noErr;
}
/*----------------------------------------------------------------------------
Zoom
Zoom a text window.
Entry: wind = pointer to text window.
zoomDir = zoom direction = inZoomIn or inZoomOut.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Zoom (WindowPtr wind, short zoomDir)
{
TWindow **info;
short width, height, lineHeight, minHeight;
Rect zoomRect, r;
WStateData **wState;
TEHandle theTE, tempTE;
Handle tempHandle;
long longHeight;
wState = (WStateData**)((WindowPeek)wind)->dataHandle;
if (zoomDir == inZoomOut) {
info = (TWindow**)GetWRefCon(wind);
lineHeight = (**info).lineHeight;
theTE = (**info).theTE;
width = 75*CharWidth('a') + 2*kTextMargin + 18;
if (width < kMinWindowWidth) width = kMinWindowWidth;
CalculateZoomRect(wind, width, kMaxShort, &zoomRect, gPrefs.dontCoverFinderIcons);
SetRect(&r, 0, 0, zoomRect.right - zoomRect.left - 15 - 2*kTextMargin, kMaxShort);
tempTE = TENew(&r, &r);
tempHandle = (**tempTE).hText;
(**tempTE).hText = (**theTE).hText;
TECalText(tempTE);
longHeight = (long)TEScrollNumTELines(tempTE) * (long)lineHeight;
longHeight += (**info).panelHeight + 15 + 2*kTextMargin;
(**tempTE).hText = tempHandle;
TEDispose(tempTE);
if (longHeight > kMaxShort) {
height = kMaxShort;
} else {
height = longHeight;
minHeight = MinHeight(wind);
if (height < minHeight) height = minHeight;
}
CalculateZoomRect(wind, width, height, &zoomRect, gPrefs.dontCoverFinderIcons);
height = zoomRect.bottom - zoomRect.top;
FixHeight(wind, &height);
zoomRect.bottom = zoomRect.top + height;
(**wState).stdState = zoomRect;
if (WindRectEqualRect(wind, &zoomRect)) return noErr;
}
EraseRect(&wind->portRect);
ZoomWindow(wind, zoomDir, false);
ResizeContents(wind);
return noErr;
}
/*----------------------------------------------------------------------------
Command
Handle a command for a text window.
Entry: wind = pointer to text window.
menu = the menu.
item = the item.
modifiers = modifiers field from event record.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Command (WindowPtr wind, short menu, short item, short modifiers)
{
OSErr err = noErr;
switch (menu) {
case kFileMenu:
switch (item) {
case kSaveItem:
err = DoSave(wind, modifiers);
break;
case kSaveAsItem:
err = DoSaveAs(wind, modifiers);
break;
case kPrintItem:
err = DoPrint(wind, modifiers);
break;
}
break;
case kEditMenu:
switch (item) {
case kCopyItem:
DoCopy(wind);
break;
case kSelectAllItem:
DoSelectAll(wind);
break;
case kFindItem:
err = DoFind(wind);
break;
case kFindAgainItem:
err = DoFindAgain(wind);
break;
case kEnterSelectionItem:
err = DoEnterSelection(wind);
break;
}
break;
}
return err;
}
/*----------------------------------------------------------------------------
Close
Close a text window.
Entry: wind = pointer to text window.
Exit: function result = error code.
----------------------------------------------------------------------------*/
static OSErr Close (WindowPtr wind)
{
TWindow **info;
info = (TWindow**)GetWRefCon(wind);
if ((**info).theTE != nil) TEDispose((**info).theTE);
MyDisposeHandle(info);
MyDisposeWindow(wind);
return noErr;
}
/*----------------------------------------------------------------------------
Idle
Handle idle time tasks for a text window.
Entry: wind = pointer to text window.
Exit: cursorRgn = cursor region for WaitNextEvent mouse moved events.
----------------------------------------------------------------------------*/
static void Idle (WindowPtr wind, RgnHandle cursorRgn)
{
TWindow **info;
TEHandle theTE;
Rect r;
Point where;
unsigned long fileEnabled, editEnabled, specialEnabled;
short selStart, selEnd;
info = (TWindow**)GetWRefCon(wind);
theTE = (**info).theTE;
TEIdle(theTE);
r = (**theTE).viewRect;
InsetRect(&r, -kTextMargin, 0);
LocalToGlobalRect(&r);
RectRgn(cursorRgn, &r);
if (gHaveDragMgr) SubtractTEHiliteRgn(cursorRgn, theTE);
GetMouse(&where);
LocalToGlobal(&where);
if (PtInRgn(where, cursorRgn)) {
SetCursor(&gIBeamCurs);
} else {
SetCursor(&qd.arrow);
ComplementRgn(cursorRgn);
}
editEnabled = kTextEditEnabled;
if (*gFindPattern == 0) editEnabled &= ~kFindAgainMask;
selStart = (**theTE).selStart;
selEnd = (**theTE).selEnd;
if (selStart >= selEnd) {
editEnabled &= ~(kCopyMask | kEnterSelectionMask);
} else if (selEnd > selStart + 255) {
editEnabled &= ~kEnterSelectionMask;
}
if (gStartupOK) {
specialEnabled = kTextSpecialEnabled;
SetMenusTo(kAppleAllEnabled, kTextFileEnabled, editEnabled,
kTextNewsEnabled, specialEnabled, kTextWindEnabled);
} else {
fileEnabled = kTextFileEnabled;
fileEnabled &= ~(kNewGroupWindowMask | kOpenMask);
SetMenusTo(kAppleAllEnabled, fileEnabled, editEnabled,
kStartupBadNewsEnabled, kStartupBadSpecialEnabled, kStartupBadWindEnabled);
}
/* For shooting screen shots of menus with all items enabled. */
#ifdef kDevelopmentVersion
{
unsigned long all = 0xffffffff;
if (gStartupOK) SetMenusTo(all, all, all, all, all, all);
}
#endif
}
/*----------------------------------------------------------------------------
Help
Handle help balloons for a text window.
Entry: wind = pointer to text window.
where = current mouse location in local coordinates.
----------------------------------------------------------------------------*/
static void Help (WindowPtr wind, Point where)
{
TWindow **info;
if (DoSizeBoxAndVerticalScrollBarBalloons(wind, where)) return;
info = (TWindow**)GetWRefCon(wind);
if (where.v < (**info).panelHeight) {
DoAboutWindowIconHelpBalloon(wind, where);
return;
}
}
/*----------------------------------------------------------------------------
InitTextDispatchTable
Initialize the dispatch table for text windows.
----------------------------------------------------------------------------*/
void InitTextDispatchTable (void)
{
TDispatch *d;
d = &gDispatch[kText];
d->activate = Activate;
d->update = Update;
d->mouse = Mouse;
d->draggable = Draggable;
d->key = Key;
d->grow = Grow;
d->zoom = Zoom;
d->command = Command;
d->close = Close;
d->idle = Idle;
d->help = Help;
gAutoScrollUPP = NewTEClickLoopProc(AutoScroll);
gScrollActionUPP = NewControlActionProc(ScrollAction);
}